package com.rslai.base.tool.servertest.extension;

import com.rslai.base.tool.servertest.util.ReflectionUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ExtensionLoader {
    private static Logger logger = LoggerFactory.getLogger(ExtensionLoader.class);
    private static final String extensionLocation = "META-INF/servertest/";

    public static <T> Map<String, Class<? extends T>> loadExtension(Class<? extends T> type)
            throws IOException {
        String fileName = "META-INF/servertest/" + type.getName();
        ClassLoader classLoader = findClassLoader();
        Enumeration resources = classLoader.getResources(fileName);
        Map result = new HashMap();
        while (resources.hasMoreElements()) {
            URL url = (URL) resources.nextElement();
            loadFile(url, type, result);
        }
        return result;
    }

    private static <T> void loadFile(URL url, Class type, Map<String, Class<? extends T>> result) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), "utf-8"));
        String line = null;
        while ((line = reader.readLine()) != null) {
            String[] keyValue = line.split("=");
            String name = keyValue[0];
            String value = keyValue[1];
            Class clazz = ReflectionUtils.loadClass(value);
            if (!type.isAssignableFrom(clazz)) {
                logger.error("{} is not subclass of {}", value, type.getName());
            } else
                result.put(name, clazz);
        }
    }

    private static ClassLoader findClassLoader() {
        return ExtensionLoader.class.getClassLoader();
    }
}
